﻿using System.Configuration.Provider;
using System.Web.Configuration;

namespace SCRUM.Core.DataProviders
{
    /// <summary>
    /// Factory - decides which provider to use based on informations from web.config 
    /// </summary>
    public static class ProviderFactory
    {
        /// <summary>
        /// Data provider
        /// </summary>
        private static DataProvider provider;

        /// <summary>
        /// Data provider collection from web.config
        /// </summary>
        private static DataProviderCollection providers;

        /// <summary>
        /// Lock object
        /// </summary>
        private static object lockObject = new object();

        /// <summary>
        /// Gets the current provider.
        /// </summary>
        public static DataProvider Provider
        {
            get 
            { 
                LoadProviders(); 
                return provider; 
            }
        }

        /// <summary>
        /// Gets a collection of all registered providers.
        /// </summary>
        public static DataProviderCollection Providers
        {
            get 
            { 
                LoadProviders(); 
                return providers; 
            }
        }

        /// <summary>
        /// Load the providers from the web.config.
        /// </summary>
        public static void LoadProviders()
        {
            // Avoid claiming lock if providers are already loaded
            if (provider == null)
            {
                lock (lockObject)
                {
                    // Do this again to make sure provider is still null
                    if (provider == null)
                    {
                        // Get a reference to the provider section
                        DataProviderSection section = (DataProviderSection)WebConfigurationManager.GetSection("DataEngine/dataProvider");

                        // Load registered providers and point provider to the default provider
                        providers = new DataProviderCollection();
                        ProvidersHelper.InstantiateProviders(section.Providers, providers, typeof(DataProvider));
                        provider = providers[section.DefaultProvider];

                        if (provider == null)
                        {
                            throw new ProviderException("Unable to load default provider");
                        }
                    }
                }
            }
        }
    }
}
